﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Timers;
using System.Net.Sockets; 
using Models;
using SerialPortHelper;
namespace MySocketHelper
{
    public class SocketClientManager
    {
        //定义,最好定义成静态的, 因为我们只需要一个就好  
         ClientManager smanager = null;
         AGVInfo agvInfo = null;
        //定义事件与委托  
        public delegate void ReceiveData(object message,string ip);
        public delegate void ServerClosed(string ip);

        public event ReceiveData OnReceiveData;
        public event ServerClosed OnServerClosed;

        /// <summary>  
        /// 心跳定时器  
        /// </summary>  
         System.Timers.Timer heartTimer = null;
        /// <summary>  
        /// 心跳包  
        /// </summary>  
        //static ApiResponse heartRes = null;

        /// <summary>  
        /// 判断是否已连接  
        /// </summary>  
        public  bool Connected
        {
            get { return smanager != null && smanager.Connected; }
        }
        /// <summary>
        /// 已登录的用户信息  
        /// </summary>
        public AGVInfo AgvInfo
        {
            get { return agvInfo; }
            set { agvInfo = value; }
        }
        /// <summary>  
        /// 已登录的用户信息  
        /// </summary>  
        //public static UserInfoModel UserInfo
        //{
        //    get { return userInfo; }
        //}


        #region 基本方法

        /// <summary>  
        /// 连接到服务器  
        /// </summary>  
        /// <returns></returns>  
        public  SocketError Connect(string ip,int port)
        {
            try
            {
                if (Connected) return SocketError.Success;
                if (string.IsNullOrWhiteSpace(ip) || port <= 1000) return SocketError.Fault;
                //创建连接对象, 连接到服务器  
                smanager = new ClientManager(ip, port);
                SocketError error = smanager.Connect();
                if (error == SocketError.Success)
                {
                    //连接成功后,就注册事件. 最好在成功后再注册.  
                    smanager.ServerDataHandler += OnReceivedServerData;
                    smanager.ServerStopEvent += OnServerStopEvent;
                }
                return error;
            }
            catch (Exception ex)
            {
                
                throw new Exception("服务端IP："+ip+"端口："+port.ToString()+"连接异常！异常信息："+ex.Message);
            }
           
        }

        /// <summary>  
        /// 断开连接  
        /// </summary>  
        public  void Disconnect()
        {
            try
            {
                smanager.Disconnect();
            }
            catch (Exception ex) { throw new Exception("服务器关闭异常，异常信息："+ex.Message); }
        }
        /// <summary>  
        /// 发送请求  
        /// </summary>  
        /// <param name="request"></param>  
        /// <returns></returns>  
       /* public static bool Send(ApiResponse request)
        {
            return Send(JsonConvert.SerializeObject(request));
        }*/

        /// <summary>  
        /// 发送消息  
        /// </summary>  
        /// <param name="message">消息实体</param>  
        /// <returns>True.已发送; False.未发送</returns>  
        public  bool Send(string message)
        {
            try
            {
                if (!Connected) return false;

                byte[] buff = new SerialPortHelper.AlgorithmHelper().From16ToBtyes(message); ;
                //加密,根据自己的需要可以考虑把消息加密  
                //buff = AESEncrypt.Encrypt(buff, m_aesKey);  
                smanager.Send(buff);
                return true;
            }
            catch (Exception ex)
            {
                
                throw new Exception(message+"发送异常;异常信息："+ex.Message);
            }
           
        }


        /// <summary>  
        /// 发送字节流  
        /// </summary>  
        /// <param name="buff"></param>  
        /// <returns></returns>  
         public bool Send(byte[] buff)
        {
            if (!this.Connected) return false;
            smanager.Send(buff);
            return true;
        }



        /// <summary>  
        /// 接收消息  
        /// </summary>  
        /// <param name="buff"></param>  
        private  void OnReceivedServerData(byte[] buff,string ip)
        {
            try
            {
                //To do something  
                //你要处理的代码,可以实现把buff转化成你具体的对象, 再传给前台  
                if (OnReceiveData != null)
                {
                    OnReceiveData(buff, ip);
                }
            }
            catch (Exception ex)
            {
                
                throw new Exception(ip+"数据接收异常！异常信息："+ex.Message);
            }               
        }
        /// <summary>  
        /// 服务器已断开  
        /// </summary>  
        private  void OnServerStopEvent(string ip)
        {
            try
            {
                if (OnServerClosed != null)
                    OnServerClosed(ip);
            }
            catch (Exception ex)
            {
                
                throw new Exception(ip+"停止异常！异常信息："+ex.Message);
            }
          
        }

        #endregion

        #region 心跳包
        //心跳包也是很重要的,看自己的需要了, 我只定义出来, 你自己找个地方去调用吧  
        /// <summary>  
        /// 开启心跳  
        /// </summary>  
        private  void StartHeartbeat()
        {
            if (heartTimer == null)
            {
                heartTimer = new System.Timers.Timer();
                heartTimer.Elapsed += TimeElapsed;
            }
            heartTimer.AutoReset = true;     //循环执行  
            heartTimer.Interval = 30 * 1000; //每30秒执行一次  
            heartTimer.Enabled = true;
            heartTimer.Start();

            //初始化心跳包  
            //heartRes = new ApiResponse((int)ApiCode.心跳);
            //heartRes.data = new Dictionary<string, object>();
            //heartRes.data.Add("beat", Function.Base64Encode(userInfo.nickname + userInfo.userid + DateTime.Now.ToString("HH:mm:ss")));
        }

        /// <summary>  
        /// 定时执行  
        /// </summary>  
        /// <param name="source"></param>  
        /// <param name="e"></param>  
         void TimeElapsed(object source, ElapsedEventArgs e)
        {
            //SocketClientManager.Send(heartRes);
        }

        #endregion  
    }
}
